(*
This file is part of the utils section of Lustre reader

* Copyright (c) 2010, Nicola Camuffo.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met->
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Nicola Camuffo, nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)


open Prfuncs
open Lustypes
open Tree_printer



let sout = output_string
let iout h x = output_string h (string_of_int x) 
let cr h = sout h "\n"
let ccr h = sout h "\n\n"

let sconstr = print_simple_constructor
let cconstr = print_complex_constructor

let slist = print_simple_list
let clist = print_complex_list


let pr_intl h l = slist h "" l iout


let print_entnamehash handle =
  let ind = "  " in
  let pr h (id,sym) = sout h ind; iout h id; sout h (" -> " ^ sym) in
  print_hash handle "" Lustables.entnamehash "<< ENTNAMEHASH >>" pr;
	ccr handle

	
let print_pmidhash handle =
  let ind = "  " in
  let pr h (sym,id) = sout h (ind ^ sym ^ " -> "); iout h id in
  print_hash handle "" Lustables.pmidhash "<< PMIDHASH >>" pr;
	ccr handle

let print_packages handle lst =
  let ind = "  " in
  let pr h id = sout h ind; iout h id in
  sout handle "<< PACKAGES >>\n";
  print_simple_list handle "" lst pr

let print_models handle lst =
  let ind = "  " in
  let pr h id = sout h ind; iout h id in
  sout handle "<< MODELS >>\n";
  print_simple_list handle "" lst pr

let print_model_instances handle lst =
  let ind = "  " in
  let pr h id = sout h ind; iout h id in
  sout handle "<< MODEL_INSTANCES >>\n";
  print_simple_list handle "" lst pr


let print_envcontainerhash handle =
  let ind = "  " in
  let pr h (id,eid) = sout h ind; iout h id; sout h " -> "; iout h eid in
  print_hash handle "" Lustables.envcontainerhash "<< ENVCONTAINERHASH >>" pr;
	ccr handle

let print_containedhash handle =
  let ind = "  " in
  let pr h (eid,idl) = sout h ind; iout h eid; sout h " -> "; pr_intl h idl  in
  print_hash handle "" Lustables.containedhash "<< CONTAINEDHASH >>" pr;
	ccr handle


let print_constidhash handle =
  let ind = "  " in
  let pr h ((eid,sym),id) = sout h ind; iout h eid; sout h (", " ^ sym ^ " -> "); iout h id in
  print_hash handle "" Lustables.constidhash "<< CONSTIDHASH >>" pr;
	ccr handle

let print_constvaluehash handle =
  let ind = "  " in
  let pr h (id,(tp,ex)) =
		let ind2 = ind ^ ind in
		sout h ind; iout h id; sout h " ->\n"; print_type h ind2 tp; sout h ",\n";
		match ex with
			E_NONE -> sout h (ind2 ^ "---")
			| e -> print_expression h ind2 (e,tp)
	in
  print_hash handle "" Lustables.constvaluehash "<< CONSTVALUEHASH >>" pr;
	ccr handle
	

let print_typeidhash handle =
  let ind = "  " in
  let pr h ((eid,sym),id) = sout h ind; iout h eid; sout h (", " ^ sym ^ " -> "); iout h id in
  print_hash handle "" Lustables.typeidhash "<< TYPEIDHASH >>" pr;
	ccr handle

let print_typevaluehash handle =
  let ind = "  " in
  let pr h (id,tp) =
		let ind2 = ind ^ ind in
		sout h ind; iout h id; sout h " ->\n";
		match tp with
			T_NONE -> sout h (ind2 ^ "---")
			| t -> print_type h ind2 t
	in
  print_hash handle "" Lustables.typevaluehash "<< TYPEVALUEHASH >>" pr;
	ccr handle

	
let print_fnidhash handle =
  let ind = "  " in
  let pr h ((nid,sym),id) = sout h ind; iout h nid; sout h (", " ^ sym ^ " -> "); iout h id in
  print_hash handle "" Lustables.fnidhash "<< FNIDHASH >>" pr;
	ccr handle

	
let print_inputshash handle =
	let ind = "  " in
	let prl h l = slist h "" l iout in
  let pr h (nid,idl) = sout h ind; iout h nid; sout h "-> "; prl h idl in
  print_hash handle "" Lustables.inputshash "<< INPUTSHASH >>" pr;
  ccr handle
	
let print_outputshash handle =
	let ind = "  " in
	let prl h l = slist h "" l iout in
  let pr h (nid,idl) = sout h ind; iout h nid; sout h "-> "; prl h idl in
  print_hash handle "" Lustables.outputshash "<< OUTPUTSHASH >>" pr;
  ccr handle
	
let print_localshash handle =
	let ind = "  " in
	let prl h l = slist h "" l iout in
  let pr h (nid,idl) = sout h ind; iout h nid; sout h "-> "; prl h idl in
  print_hash handle "" Lustables.localshash "<< LOCALSHASH >>" pr;
  ccr handle

let print_additionalshash handle =
	let ind = "  " in
	let prl h l = slist h "" l iout in
  let pr h (nid,idl) = sout h ind; iout h nid; sout h "-> "; prl h idl in
  print_hash handle "" Lustables.additionalshash "<< ADDITIONALSHASH >>" pr;
  ccr handle


let print_varidhash handle =
  let ind = "  " in
  let pr h ((nid,sym),id) = sout h ind; iout h nid; sout h (", " ^ sym ^ " -> "); iout h id in
  print_hash handle "" Lustables.varidhash "<< VARIDHASH >>" pr;
	ccr handle

let print_vartypehash handle =
  let ind = "  " in
  let pr h (id,tp) =
		let ind2 = ind ^ ind in
		sout h ind; iout h id; sout h " ->\n"; print_type h ind2 tp
	in
  print_hash handle "" Lustables.vartypehash "<< VARTYPEHASH >>" pr;
	ccr handle
	

let print_assignedexprshash handle =
  let ind = "  " in
	let ind2 = ind ^ ind in
	let prl h l = clist h "" l (fun h (lhs,rhs) -> print_lhs h ind2 lhs; cr handle; print_expression h ind2 rhs) in
  let pr h (nid,l) = sout h ind; iout h nid; sout h "->\n"; prl h l in
  print_hash handle "" Lustables.assignedexprshash "<< ASSIGNEDEXPRSHASH >>" pr;
	ccr handle
		

	
let print_data handle =	
	print_entnamehash handle;
	print_pmidhash handle;
	print_constidhash handle;
	print_constvaluehash handle;
	print_typeidhash handle;
	print_typevaluehash handle;
	print_fnidhash handle;
	print_inputshash handle;
	print_outputshash handle;
	print_localshash handle;
	print_additionalshash handle;
	print_varidhash handle;
	print_vartypehash handle;
	print_assignedexprshash handle


(*
  out handle "<< CONSTHASH >>\n";
  let consthash = data#get_consthash () in

  let pr h s (e,t) = out h ind; out h s; out h ":\n"; print_expression h ind e; out h "\n"; print_type h ind t in
  print_complex_hash handle spaces consthash pr;
  out handle "\n\n";


  out handle "<< TYPEDEFHASH >>\n";
  let typedefhash = data#get_typedefhash () in

  let pr h s t = out h ind; out h s; out h ":\n"; print_type h ind t in
  print_complex_hash handle spaces typedefhash pr;
  out handle "\n\n";


  out handle "<< VARIDHASH >>\n";
  let varidhash = data#get_varidhash () in

  let pr h (nid,n) id = out h ind; out h (string_of_int nid); out h ","; out h n; out h ": "; out h (string_of_int id) in
  print_complex_hash handle spaces varidhash pr;
  out handle "\n\n";


  out handle "<< VARNAMEHASH >>\n";
  let varnamehash = data#get_varnamehash () in


  let pr h nid s = out h ind; out h (string_of_int nid); out h ": "; out h s in
  print_complex_hash handle spaces varnamehash pr;
  out handle "\n\n";


  out handle "<< VARTYPEHASH >>\n";
  let vartypehash = data#get_vartypehash () in

  let pr h id t = out h ind; out h (string_of_int id); out h ": "; out h "\n"; print_type h ind t in
  print_complex_hash handle spaces vartypehash pr;
  out handle "\n\n";


  out handle "<< NODEMEMBERIDHASH >>\n";
  let nodememberidhash = data#get_nodememberidhash () in

  let pr h id nid = out h ind; out h (string_of_int id); out h ": "; out h (string_of_int nid) in
  print_complex_hash handle spaces nodememberidhash pr;
  out handle "\n\n";


  out handle "<< INPUTVARSHASH >>\n";
  let inputvarshash = data#get_inputvarshash () in

  let prl h l = print_simple_list h ind l (fun h x -> out h (data#get_varname x)) in
  let pr h nid idl = out h ind; out h (string_of_int nid); out h ": "; prl h idl in
  print_complex_hash handle spaces inputvarshash pr;
  out handle "\n\n";


  out handle "<< OUTPUTVARSHASH >>\n";
  let outputvarshash = data#get_outputvarshash () in

  let prl h l = print_simple_list h ind l (fun h x -> out h (data#get_varname x)) in
  let pr h nid idl = out h ind; out h (string_of_int nid); out h ": "; prl h idl in
  print_complex_hash handle spaces outputvarshash pr;
  out handle "\n\n";


  out handle "<< LOCALVARSHASH >>\n";
  let localvarshash = data#get_localvarshash () in

  let prl h l = print_simple_list h ind l (fun h x -> out h (data#get_varname x)) in
  let pr h nid idl = out h ind; out h (string_of_int nid); out h ": "; prl h idl in
  print_complex_hash handle spaces localvarshash pr;
  out handle "\n\n";


  out handle "<< NODEIDHASH >>\n";
  let nodeidhash = data#get_nodeidhash () in

  let pr h n id = out h ind; out h n; out h ": "; out h (string_of_int id) in
  print_complex_hash handle spaces nodeidhash pr;
  out handle "\n\n";


  out handle "<< NODENAMEHASH >>\n";
  let nodenamehash = data#get_nodenamehash () in

  let pr h id n = out h ind; out h (string_of_int id); out h ": "; out h n in
  print_complex_hash handle spaces nodenamehash pr;
  out handle "\n\n";


  out handle "<< SIMPLEVARSHASH >>\n";
  let simplevarshash = data#get_simplevarshash () in

  let prl h l = print_simple_list h ind l (fun h x -> out h (data#get_varname x)) in
  let pr h ni idl = out h ind; out h (data#get_varname ni); out h ": "; prl h idl in
  print_complex_hash handle spaces simplevarshash pr;
  out handle "\n\n";


  out handle "<< COMPLEXVARHASH >>\n";
  let complexvarhash = data#get_complexvarhash () in

  let pr h sid cid  = out h ind; out h (data#get_varname sid); out h ": "; out h (data#get_varname cid) in
  print_complex_hash handle spaces complexvarhash pr;
  out handle "\n\n";


  out handle "<< PROPERTIESHASH >>\n";
  let propertieshash = data#get_propertieshash () in

  let pr h nid ex = out h ind; out h (string_of_int nid); out h ":\n "; print_expression h ind ex in
  print_complex_hash handle spaces propertieshash pr;
  out handle "\n\n";


  out handle "<< ASSERTSHASH >>\n";
  let assertshash = data#get_assertshash () in

  let pr h nid ex = out h ind; out h (string_of_int nid); out h ":\n "; print_expression h ind ex in
  print_complex_hash handle spaces assertshash pr;
  out handle "\n\n";


  out handle "<< FIELDIDHASH >>\n";
  let fieldidhash = data#get_fieldidhash () in

  let pr h (cid,n) id = out h ind; out h (data#get_varname cid); out h ","; out h n; out h ": "; out h (data#get_varname id) in
  print_complex_hash handle spaces fieldidhash pr;
  out handle "\n\n";


  out handle "<< FIELDNAMEHASH >>\n";
  let fieldnamehash = data#get_fieldnamehash () in

  let pr h id s = out h ind; out h (data#get_varname id); out h ": "; out h s in
  print_complex_hash handle spaces fieldnamehash pr;
  out handle "\n\n";

(*
  out handle "<< TUPFIELDIDHASH >>\n";
  let prl h l = print_simple_list h ind l (fun h x -> out h (string_of_int x)) in
  let pr h (cid,posl) id = out h ind; out h (get_varname cid); out h ","; prl h posl; out h ": "; out h (get_varname id) in
  print_complex_hash handle spaces tupfieldidhash pr;
  out handle "\n\n";

  out handle "<< TUPFIELDPOSHASH >>\n";
  let prl h l = print_simple_list h ind l (fun h x -> out h (string_of_int x)) in
  let pr h id posl = out h ind; out h (get_varname id); out h ": "; prl h posl in
  print_complex_hash handle spaces tupfieldposhash pr;
  out handle "\n\n";
*)

  out handle "<< ADDITIONALVARSHASH >>\n";
  let additionalvarshash = data#get_additionalvarshash () in

  let prl h l = print_simple_list h ind l (fun h x -> out h (data#get_varname x)) in
  let pr h nid idl = out h ind; out h (string_of_int nid); out h ": "; prl h idl in
  print_complex_hash handle spaces additionalvarshash pr;
  out handle "\n\n"

(*
  out handle "<< COMPLEXSYMHASH >>\n";
  let pr h id s = out h ind; out h (get_varname id); out h ": "; out h s in
  print_complex_hash handle spaces complexsymshash pr;
  out handle "\n\n"
*)
*)
